#include "engine.h"
#include "entity.h"
#include "script/script.h"
#include "game.h"
//#include "3rdparty/angelscript/source/as_scriptobject.h"

//entity id server
namespace entity_id_server
{
	static unsigned int entity_id_counter=0;
	static std::map<unsigned int, entity_t*> entity_id_map;

	void init()
	{
		ASSERT(entity_id_counter==0);
		entity_id_map.insert(pair<unsigned,entity_t*>(0,(entity_t*)NULL));
		++entity_id_counter;
	}

	entity_t* get_entity(int id)
	{
		map<unsigned,entity_t*>::iterator it=entity_id_server::entity_id_map.find(id);
		if (it==entity_id_server::entity_id_map.end())
		{
#if !defined(LEO_DESIGNER) && defined(_DEBUG)
			ASSERTTXT(0,_str("%d id-ju entity nem is van!",id));
#endif
			return NULL;
		}
		return it->second;
	}

	void add_entity(entity_t* e)
	{
		ASSERT(e);
		e->entityID=entity_id_counter;
		std::pair<std::map<unsigned,entity_t*>::iterator,bool> res=entity_id_map.insert(pair<unsigned,entity_t*>(entity_id_counter,e));
		ASSERT(res.second);
		++entity_id_counter;
	}

	void add_entity_with_current_id(entity_t* e)
	{
		ASSERT(e);
		std::pair<std::map<unsigned,entity_t*>::iterator,bool> res=entity_id_map.insert(pair<unsigned,entity_t*>(e->entityID,e));
		ASSERT(res.second);
	}

	void remove_entity(entity_t* e)
	{
		entity_id_map.erase(e->entityID);
	}
}

entity_t* entity_ptr_t::get()
{
	map<unsigned,entity_t*>::iterator it=entity_id_server::entity_id_map.find(entityID);
	if (it==entity_id_server::entity_id_map.end())
	{
#if !defined(LEO_DESIGNER) && defined(_DEBUG)
		ASSERTTXT(0,_str("%d id-ju entity nem is van!",entityID));
#endif
		return NULL;
	}
	return it->second;
}

DEFINE_ROOT_ENTITY(entity_t);
PROPERTY_BINDING_BEGIN(entity_t)
	BIND_PROPERTY(entity_t,activate_at_startup,bool);
	BIND_PROPERTY(entity_t,initiallocalmtx,float4x4);
//	BIND_PROPERTY(entity_t,initialworldmtx,float4x4);
	BIND_PROPERTY(entity_t,name,stringhash);
	BIND_PROPERTY(entity_t,script_type,string);
//	BIND_PROPERTY(entity_t,script_init_function_name,string);
//	BIND_PROPERTY(entity_t,script_update_function_name,string);
//	BIND_PROPERTY(entity_t,script_exit_function_name,string);
//	BIND_PROPERTY(entity_t,script_message_handler_function_name,string);
	BIND_PROPERTY(entity_t,script_parameters,json);

PROPERTY_BINDING_END

entity_t::entity_t()
{
	flags=0;
	activate_at_startup=true;
	prev=next=parent=child=lastchild=NULL;
	initiallocalmtx.identity();
	name="xxx";

	script_init_func_id=0;
	script_update_func_id=0;
	script_exit_func_id=0;
	script_msg_func_id=0;
	script_type_id=0;
	script_object=0;

#ifdef LEO_DESIGNER
	selected=false;
#endif
}

entity_t::~entity_t()
{
	if (script_object)
	((asIScriptObject*)script_object)->Release();
}

#ifdef LEO_DESIGNER
void entity_t::onchangeproperty(const stringhash& propname)
{
	if (propname=="initiallocalmtx")
	{
		setlocalmtx(initiallocalmtx);
	}
/*
	else if (propname=="script_init_function_name")
	{
		script_init_func_id=0;
		if (script_init_function_name.size())
			script_init_func_id=SCRIPTMAN->script_engine->GetModule(0)->GetFunctionIdByName(script_init_function_name.c_str());

		ASSERTTXT(script_init_func_id>=0,_str("wrong script function name:%s",script_init_function_name.c_str()));
	}
	else if (propname=="script_update_function_name")
	{
		script_update_func_id=0;
		if (script_update_function_name.size())
			script_update_func_id=SCRIPTMAN->script_engine->GetModule(0)->GetFunctionIdByName(script_update_function_name.c_str());

		ASSERTTXT(script_update_func_id>=0,_str("wrong script function name:%s",script_update_function_name.c_str()));
	}
	else if (propname=="script_exit_function_name")
	{
		script_exit_func_id=0;
		if (script_exit_function_name.size())
			script_exit_func_id=SCRIPTMAN->script_engine->GetModule(0)->GetFunctionIdByName(script_exit_function_name.c_str());

		ASSERTTXT(script_exit_func_id>=0,_str("wrong script function name:%s",script_exit_function_name.c_str()));

	}
	else if (propname=="script_message_handler_function_name")
	{
		script_msg_func_id=0;
		if (script_message_handler_function_name.size())
			script_msg_func_id=SCRIPTMAN->script_engine->GetModule(0)->GetFunctionIdByName(script_message_handler_function_name.c_str());

		ASSERTTXT(script_msg_func_id>=0,_str("wrong script function name:%s",script_message_handler_function_name.c_str()));
	}
*/
}

void entity_t::save_recursive(string& s)
{
	s+=get_metaobject()->to_string(this);
	if (child)
	{
		s+=",\n\"child\":\n{\n";
		for (entity_t* ptr=child; ptr; ptr=ptr->next)
		{
			ptr->save_recursive(s);
			if (ptr->next)
				s+=",\n";
		}
		s+="\n}";
	}
	s+="\n}";

}
#include "file/file.h"

void entity_t::save_to_file(const char* filename)
{
	file_t file;
	file.open(filename,"wb");

	string s;
	s.reserve(1024*1024*8);
	s="{\n";
	save_recursive(s);
	s+="\n}\n";

	file.writestring(s);
	file.close();

}
#endif

void entity_t::initrecursive()
{
	if (isactive())
		return;
	initthis();

	if (isactive())
	{
		for (entity_t* ptr=child; ptr; ptr=ptr->next)
			ptr->initrecursive();
	}
}

void entity_t::updaterecursive()
{
	if (!isactive())
		return;

	update();

	for (entity_t* ptr=child; ptr; ptr=ptr->next)
		ptr->updaterecursive();
}

void entity_t::renderrecursive(bool everything/* =false */)
{
	if (!isactive() && !everything)
		return;

	render();

	for (entity_t* ptr=child; ptr; ptr=ptr->next)
		ptr->renderrecursive(everything);
}

void entity_t::exitrecursive()
{
	if (!isactive())
		return;

	for (entity_t* ptr=child; ptr; ptr=ptr->next)
		ptr->exitrecursive();

	exit();
	flags&=~ENTITY_ACTIVE;
}

void entity_t::eraserecursive()
{
	for (entity_t* ptr=child; ptr;)
	{
		entity_t* nextptr=ptr->next;
		ptr->eraserecursive();
		ptr=nextptr;
	}

	delete this;

}

bool entity_t::isactive() const
{
	return flags & ENTITY_ACTIVE;
}

void entity_t::activate()
{
	if (!parent || parent->isactive())
	{
		int f=flags & ENTITY_TO_BE_ACTIVATED;
		setflag(ENTITY_TO_BE_ACTIVATED);
		initrecursive();
		flags=(flags & (~ENTITY_TO_BE_ACTIVATED))|f;
	}
#if defined(_DEBUG)
	else
	{
		ASSERTTXT(0,_str("%s nevu entitast akarnad aktivalni, amikor a szuleje, aki %s, nem is aktiv",name.c_str(),parent->name.c_str()));
	}
#endif
}

void entity_t::deactivate()
{
	exitrecursive();
}

void entity_t::onload()
{
	if (activate_at_startup)
		setflag(ENTITY_TO_BE_ACTIVATED);
	else
		clearflag(ENTITY_TO_BE_ACTIVATED);

	localmtx=initiallocalmtx;

	init_script_function_ids();

}

void entity_t::init_script_function_ids()
{
	if (script_object)
		((asIScriptObject*)script_object)->Release();
	script_init_func_id=0;
	script_update_func_id=0;
	script_exit_func_id=0;
	script_msg_func_id=0;
	script_type_id=0;
	script_object=0;

/*
	if (script_init_function_name.size())
		script_init_func_id=SCRIPTMAN->script_engine->GetModule(0)->GetFunctionIdByName(script_init_function_name.c_str());

	if (script_update_function_name.size())
		script_update_func_id=SCRIPTMAN->script_engine->GetModule(0)->GetFunctionIdByName(script_update_function_name.c_str());
	if (script_exit_function_name.size())
		script_exit_func_id=SCRIPTMAN->script_engine->GetModule(0)->GetFunctionIdByName(script_exit_function_name.c_str());
	if (script_message_handler_function_name.size())
		script_msg_func_id=SCRIPTMAN->script_engine->GetModule(0)->GetFunctionIdByName(script_message_handler_function_name.c_str());
*/


	if (script_type.size())
	{
		script_type_id=SCRIPTMAN->script_engine->GetModule(0)->GetTypeIdByDecl(script_type.c_str()); ASSERTTXT(script_type_id>=0,_str("%s not a valid type name",script_type.c_str()));
		asIObjectType * type= SCRIPTMAN->script_engine->GetObjectTypeById(script_type_id);

		asIScriptFunction *factory = type->GetFactoryByDecl(_str("%s @%s()",script_type.c_str(),script_type.c_str()));

		asIScriptContext* context=SCRIPTMAN->get_context();
		context->Prepare(factory);

		context->Execute();

		asIScriptObject *obj = *(asIScriptObject**)context->GetAddressOfReturnValue();

		obj->AddRef();
		script_object=obj;

		uint32 pcount=obj->GetPropertyCount();

		for (unsigned n=0; n<pcount; ++n)
		{
			if (!strcmp(obj->GetPropertyName(n),"entity"))
			{
				int* entityproperty=(int*)obj->GetAddressOfProperty(n);
				*entityproperty=(int)this;
				break;
			}
		}

		asIScriptFunction* initfunction=type->GetMethodByDecl("void init()");
		if (initfunction)
			script_init_func_id=initfunction->GetId();

		asIScriptFunction* updatefunction=type->GetMethodByDecl("void update()");
		if (updatefunction)
			script_update_func_id=updatefunction->GetId();

		asIScriptFunction* exitfunction=type->GetMethodByDecl("void exit()");
		if (exitfunction)
			script_exit_func_id=exitfunction->GetId();
	}
}

void entity_t::initthis()
{
	if (!isflagset(ENTITY_TO_BE_ACTIVATED))
	{
//		ASSERTTXT(0,"ezt nem kell aktivalni");
		return;
	}

	setflag(ENTITY_ACTIVE);
	localmtx=initiallocalmtx;
	clearflag(ENTITY_VALID_WORLDMTX);
	init();
}

bool entity_t::isflagset(int flag) const
{
	return (flags & flag)!=0;
}

void entity_t::setflag(int flag)
{
	flags|=flag;
}

void entity_t::clearflag(int flag)
{
	flags&=~flag;
}


void entity_t::addchild(entity_t* e)
{
	if (e->parent)
		e->parent->removechild(e);

	e->parent=this;

	if (lastchild)
	{
		lastchild->next=e;
		e->prev=lastchild;
		lastchild=e;
	}
	else
	{
		child=lastchild=e;
	}
}

void entity_t::add_after(entity_t* e)
{
	if (e->parent)
		e->parent->removechild(e);

	e->parent=parent;
	e->prev=this;
	if (next)
		next->prev=e;
	e->next=next;
	next=e;
	if (parent->lastchild==this)
		parent->lastchild=e;
}

void entity_t::add_before(entity_t* e)
{
	if (e->parent)
		e->parent->removechild(e);

	e->parent=parent;
	e->next=this;
	if (prev)
		prev->next=e;
	e->prev=prev;
	prev=e;
	if (parent->child==this)
		parent->child=e;
}

void entity_t::removechild(entity_t* e)
{
	ASSERT(e->parent==this);
	if (e->prev)
		e->prev->next=e->next;
	else
		child=e->next;

	if (e->next)
		e->next->prev=e->prev;
	else
		lastchild=e->prev;

	e->prev=e->next=e->parent=NULL;
}

entity_t* load_scene(json_object_t& o,const stringhash& name)
{
	entityfactory_t * factory=factorymanager_t::get_metaobject(name);

	if (!factory)
	{
		ASSERTTXT(0,_str("%s tipusu entity nem is van",name.c_str()));
		return NULL;
	}

	entity_t* newnode=(entity_t*)factory->create();
	factory->load_properties(newnode,&o);

	newnode->onload();

	json_value_t* ch=o.get_value("child");

	if (ch)
	{
		json_object_t& childo=ch->get_object();
		for (uint32 n=0; n<childo.size(); ++n)
		{
			entity_t* child=load_scene(childo.pair_list[n].val.get_object(),childo.pair_list[n].key);

			if (child)
				newnode->addchild(child);
		}
	}	

	return newnode;
}

entity_t* load_scene_from_file(const char* filename)
{
	string fn(filename); fn+=".scn";
	json_object_t* o=generate_json_map(fn.c_str());

	if (!o || !o->size())
	{
		delete o;
		return 0;
	}

	entity_t* ret=load_scene(o->pair_list[0].val.get_object(),o->pair_list[0].key);
	delete o;
	return ret;
}

const float4x4& entity_t::getworldmtx()
{
	validateworldmtx();
	return worldmtx;
}

void entity_t::setlocalmtx(const float4x4& m)
{
	localmtx=m;
	invalidateworldmtx();
}

void entity_t::setworldmtx(const float4x4& m)
{
	worldmtx=m;

	if (parent)
	{
		float4x4 parentinverse; parentinverse.invert(parent->getworldmtx());
		localmtx.mul(worldmtx,parentinverse);
	}
	else
	{
		localmtx=worldmtx;
	}

	flags|=ENTITY_VALID_WORLDMTX;
	//validate_counter++;
	for (entity_t* ptr=child ; ptr ; ptr=ptr->getnextpo(this))
		ptr->flags&=~ENTITY_VALID_WORLDMTX;
}

void entity_t::setworldposition(const float3& v)
{
	validateworldmtx();
	worldmtx.axis(3)=v;

	if (parent)
	{
		float4x4 parentinverse; parentinverse.invert(parent->getworldmtx());
		localmtx.mul(worldmtx,parentinverse);
	}
	else
	{
		localmtx=worldmtx;
	}

	flags|=ENTITY_VALID_WORLDMTX;
	//validate_counter++;
	for (entity_t* ptr=child ; ptr ; ptr=ptr->getnextpo(this))
		ptr->flags&=~ENTITY_VALID_WORLDMTX;
}

void entity_t::validateworldmtx()
{
	if (!(flags & ENTITY_VALID_WORLDMTX))
	{
		if (parent)
//			worldmtx.mul4x3(localmtx,parent->getworldmtx());
			worldmtx.mul(localmtx,parent->getworldmtx());
		else
			worldmtx=localmtx;
		flags|=ENTITY_VALID_WORLDMTX;
		//validate_counter++;
	}
}

void entity_t::invalidateworldmtx()
{
	for (entity_t* ptr=this; ptr; ptr=ptr->getnextpo(this))
		ptr->flags&=~ENTITY_VALID_WORLDMTX;
}

#ifdef LEO_DESIGNER
float4x4 entity_t::getinitialworldmtx()
{
	if (!parent)
		return initiallocalmtx;
	else
	{
		float4x4 wm;
		wm.mul(initiallocalmtx,parent->getinitialworldmtx());
		return wm;
	}
}

void entity_t::setinitialworldmtx(const float4x4& wm)
{
	float4x4 parentworld;
	if (parent)
		parentworld=parent->getinitialworldmtx();
	else
		parentworld.identity();

	float4x4 invparentworld;
	invparentworld.invert(parentworld);
	initiallocalmtx.mul(wm,invparentworld);
}


#endif

entity_t* entity_t::getnextpo(entity_t* root) const
{
	if (child)
		return child;

	return getnextpo_up(root);

}

entity_t* entity_t::getnextpo_up(entity_t* root) const
{
	for (const entity_t* ptr=this; ptr!=root; ptr=ptr->parent)
		if (ptr->next)
			return ptr->next;
	return NULL;
}




void entity_t::init()
{
	script_states.clear();
#ifdef LEO_DESIGNER
	init_script_function_ids();
#endif

	if (script_init_func_id)
	{
		asIScriptContext* context=SCRIPTMAN->get_context();
		int r;
		r=context->Prepare(script_init_func_id);ASSERT(r>=0);
		if (script_object)
		{
			r=context->SetObject(this->script_object);
		}
		else
		{
			ASSERT(0);
			r=context->SetArgDWord(0,(int)this);ASSERT(r>=0);
		}
		r=context->Execute();ASSERT(r>=0);
	}

}

void entity_t::update()
{
	if (script_update_func_id)
	{
		asIScriptContext* context=SCRIPTMAN->get_context();
		int r;
		r=context->Prepare(script_update_func_id);ASSERT(r>=0);
		if (script_object)
		{	
			int rc=		((asIScriptObject*)script_object)->AddRef();
			rc=		((asIScriptObject*)script_object)->Release();
			ASSERT(rc==1);

			r=context->SetObject(this->script_object);
		}
		else
		{
			ASSERT(0);
			r=context->SetArgDWord(0,(int)this);ASSERT(r>=0);
		}
		r=context->Execute();ASSERT(r>=0);
	}

}

void entity_t::render()
{

}

void entity_t::exit()
{
	if (script_object)
	{
		if (script_exit_func_id)
		{
			asIScriptContext* context=SCRIPTMAN->get_context();
			int r;
			r=context->Prepare(script_exit_func_id);ASSERT(r>=0);
			r=context->SetObject(this->script_object);
			r=context->Execute();ASSERT(r>=0);
		}

	}



}

void entity_t::messagehandler(const stringhash& messageID, const json_object_t& messageparam)
{
/*
	if (script_msg_func_id)
	{
		asIScriptContext* context=SCRIPTMAN->get_context();
		int r;
		r=context->Prepare(script_msg_func_id);ASSERT(r>=0);
		r=context->SetArgDWord(0,(int)this);ASSERT(r>=0);
		objectref o;
		r=context->SetArgDWord(3,messageID.value);ASSERT(r>=0);
		o.objptr=(json_object_t*)&messageparam;
		r=context->SetArgObject(4,&o);ASSERT(r>=0);

		r=context->Execute();
	}
*/
}

entity_t* entity_t::clone()
{
	entityfactory_t* mo=this->get_metaobject();
	entity_t* e=(entity_t*)mo->create();

	while (mo)
	{
		for (unsigned int n=0; n<mo->get_propertycount(); ++n)
		{
			property_t* pd=mo->get_property(n);
			pd->clone(e,this);
		}
		mo=mo->parent;
	}

	e->onload();

	return e;
}

entity_t* entity_t::clonerecursive()
{
	entity_t* e=clone();


	for (entity_t* ptr=child; ptr; ptr=ptr->next)
	{
		entity_t* c=ptr->clonerecursive();
		e->addchild(c);
	}

	return e;
}



//script fuggvenyek
void get_world_position(entity_t* e, float3& pos)
{
	pos=e->getworldmtx().translate();
}

float3 get_world_position2(entity_t* e)
{
	return e->getworldmtx().translate();
}

float3 get_world_rotation(entity_t* e)
{
	float3 rot;
	e->getworldmtx().to_rotation(rot.x,rot.y,rot.z);

	return rot;
}

float4x4 get_local_matrix(entity_t* e)
{
	return e->localmtx;
}

float4x4 getworldmtx(entity_t* e)
{
	return e->getworldmtx();
}

void setworldmtx(entity_t* e, const float4x4& mtx)
{
	e->setworldmtx(mtx);
}

void set_local_position(entity_t* e,const float3& pos)
{
	float4x4 mtx=e->localmtx;
	mtx.translate()=pos;
	e->setlocalmtx(mtx);
}

void setlocalmtx(entity_t* e,const float4x4& mtx)
{
	e->setlocalmtx(mtx);
}

float3 get_local_position(entity_t* e)
{
	return e->localmtx.translate();
}

void set_world_position(entity_t* e, const float3& pos)
{
	float4x4 m=e->getworldmtx();
	m.translate()=pos;
	e->setworldmtx(m);
}

void get_rotation(entity_t* e, float3& rot)
{
	e->getworldmtx().to_rotation(rot.x,rot.y,rot.z);
}

void get_scale(entity_t* e, float3& scale)
{
	scale=e->getworldmtx().get_scale();
}

void set_scale(entity_t* e, const float3& scale)
{
	float4x4 m=e->getworldmtx();
	m.normalize();
	m.scale(scale.x,scale.y,scale.z);
	e->setworldmtx(m);
}

void set_rotation(entity_t* e, const float3& rot)
{
	float4x4 m=e->getworldmtx();
	m.from_rotation(rot.x,rot.y,rot.z);
	e->setworldmtx(m);
}

int get_string_hash(const string& str)
{
	return (int)stringhash::get(str).value;
}

entity_t* get_dynamic_entity(int id)
{
	return entity_id_server::get_entity(id);
}

int get_entity_id(entity_t* e)
{
	return e->entityID;
}

#include "game.h"
#include "scene.h"

int add_dynamic_entity_id(entity_t* proto,const float4x4& mtx)
{
	return GAME->scene->add_dynamic_entity(proto,mtx).entityID;
}

void add_dynamic_entity(entity_t* proto,const float4x4& mtx)
{
	GAME->scene->add_dynamic_entity_ptr(proto,mtx);
}

entity_t* add_dynamic_entity_ptr(entity_t* proto,const float4x4& mtx)
{
	return GAME->scene->add_dynamic_entity_ptr(proto,mtx);
}


float _cdecl float_rand(float min,float max)
{
	return sfrand(min,max);
}

int __cdecl int_rand(int min, int max)
{
	return srand(min,max);
}

void generate_particle(const string& name, const float3& pos)
{
	float4x4 mtx(float4x4::identity_matrix);
	mtx.translate()=pos;
	entity_t* e=GAME->scene->add_dynamic_entity_ptr(GAME->scene->getentity(name.c_str()),mtx);
	if (e)
		e->flags|=ENTITY_DYNAMIC_ERASE_IF_POSSIBLE;
}

void generate_particle_mtx(const string& name, const float4x4& pos)
{
	entity_t* e=GAME->scene->add_dynamic_entity_ptr(GAME->scene->getentity(name.c_str()),pos);
	if (e)
		e->flags|=ENTITY_DYNAMIC_ERASE_IF_POSSIBLE;
}

void script_assert(bool b, const string& str)
{
	ASSERTTXT(b,str.c_str());
}

objectref get_script_entity_state_object(entity_t* e)
{
	objectref o;
	o.objptr=&e->script_states;

	return o;
}

objectref get_script_entity_param_object(entity_t* e)
{
	objectref o;
	o.objptr=&e->script_parameters;

	return o;
}

void activate_entity(entity_t* e)
{
	e->activate();
}

void deactivate_entity(entity_t* e)
{
	e->deactivate();
}

void end_game()
{
	GAME->endgame=true;
}


script_fn_registering_begin(game)
register_script_fn("void end_game()",end_game);
register_script_fn("void get_world_position(int,float3& out)",get_world_position);
register_script_fn("float3 get_world_position(int)",get_world_position2);
register_script_fn("void set_world_position(int,const float3& in)",set_world_position);
register_script_fn("void get_rotation(int,float3& out)",get_rotation);
register_script_fn("void set_rotation(int,const float3& in)",set_rotation);
register_script_fn("void get_scale(int,float3& out)",get_scale);
register_script_fn("void set_scale(int,const float3& in)",set_scale);
register_script_fn("float4x4 get_local_matrix(int)",get_local_matrix);
register_script_fn("float4x4 get_world_matrix(int)",getworldmtx);
register_script_fn("void set_world_matrix(int,const float4x4& in)",setworldmtx);
register_script_fn("void set_local_position(int,const float3& in)",set_local_position);
register_script_fn("void set_local_matrix(int,const float4x4& in)",setlocalmtx);
register_script_fn("float3 get_local_position(int)",get_local_position);
register_script_fn("map get_states(int)",get_script_entity_state_object);
register_script_fn("map get_parameters(int)",get_script_entity_param_object);


register_script_fn("int get_string_id(const string& in)",get_string_hash);
register_script_fn("int add_dynamic_entity_id(int,const float4x4& in)",add_dynamic_entity_id);
register_script_fn("int add_dynamic_entity_ptr(int,const float4x4& in)",add_dynamic_entity_ptr);
register_script_fn("void add_dynamic_entity(int,const float4x4& in)",add_dynamic_entity);
register_script_fn("int get_dynamic_entity(int)",get_dynamic_entity);
register_script_fn("int get_entity_id(int)",get_entity_id);
register_script_fn("float rand(float,float)",float_rand);
register_script_fn("int rand_int(int,int)",int_rand);

register_script_fn("void generate_particle(const string& in,const float3& in)",generate_particle);
register_script_fn("void generate_particle(const string& in,const float4x4& in)",generate_particle_mtx);

register_script_fn("void script_assert(bool,const string& in)",script_assert);
register_script_fn("void activate(int)",activate_entity);
register_script_fn("void deactivate(int)",deactivate_entity);
script_fn_registering_end




